package cn.demoncat.util.io;

import cn.demoncat.util.exception.IoRuntimeException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.comparator.*;

import java.io.File;
import java.util.Comparator;
import java.util.Date;

/**
 * 文件比较工具：相等、比较、排序
 * 
 * @author 延晓磊
 *
 * @since 2016年6月3日
 */
public final class FileCompareUtil {

	/**
	 * 判断文件的最后修改日期是否比目标文件新
	 * 
	 * @param file
	 * @param descFile
	 * @return 如果两个文件为空或不存在，返回false
	 * @throws IoRuntimeException 判断失败
	 */
	public static boolean isNew(File file, File descFile){
		if (file == null || descFile == null || ! file.exists() || ! descFile.exists()) {
			return false; 
		}
		try{
			return FileUtils.isFileNewer(file, descFile);
		}catch(Exception e){
			throw new IoRuntimeException("比较文件的最后修改日期失败："+ e.getMessage(), e);
		}
	}

	/**
	 * 判断文的最后修改日期是否比指定日期新
	 * 
	 * @param file
	 * @param date
	 * @return 如果文件为空或不存在、或者日期为空，返回false
	 * @throws IoRuntimeException   如果判断失败则抛出
	 */
	public static boolean isNew(File file, Date date){
		if (file == null || date == null || ! file.exists()) {
			return false; 
		}
		try{
			return FileUtils.isFileNewer(file, date);
		}catch(Exception e){
			throw new IoRuntimeException("比较文件的最后修改日期失败："+ e.getMessage(), e);
		}
	}

	/**
	 * 比较文件：比较是否指向同一文件、将逐字节比较内容
	 * 
	 * @param file1
	 * @param file2 
	 * @return 
	 * @throws IoRuntimeException  如果比较失败则抛出
	 */
	public static boolean equals(File file1, File file2){
		try{
			return FileUtils.contentEquals(file1, file2); 
		}catch(Exception e){
			throw new IoRuntimeException("比较文件内容失败："+ e.getMessage(), e);
		}
	}

	/**
	 * 比较文本文件：比较是否指向同一文件、将根据UTF-8字符集比较文本内容
	 * 
	 * @param file1
	 * @param file2 
	 * @return 
	 * @throws IoRuntimeException  如果比较失败则抛出
	 */
	public static boolean euqalsTxt(File file1, File file2){
		try{
			return FileUtils.contentEqualsIgnoreEOL(file1, file2,"UTF-8"); 
		}catch(Exception e){
			throw new IoRuntimeException("比较文件内容失败："+ e.getMessage(), e);
		}
	}

	/**
	 * 文件比较器
	 */
	public static final class FileComparer{
 
		/**
		 * 文件名正序，区分大小写
		 */
		public static final Comparator<File> NameAsc = NameFileComparator.NAME_COMPARATOR;
		/**
		 * 文件名逆序，区分大小写
		 */
		public static final Comparator<File> NameDesc = NameFileComparator.NAME_REVERSE;
		/**
		 * 文件名正序，不区分大小写
		 */
		public static final Comparator<File> NameAsc2 = NameFileComparator.NAME_INSENSITIVE_COMPARATOR;
		/**
		 * 文件名逆序，不区分大小写
		 */
		public static final Comparator<File> NameDesc2 = NameFileComparator.NAME_INSENSITIVE_REVERSE;
		/**
		 * 文件路径名正序，区分大小写
		 */
		public static final Comparator<File> PathAsc = PathFileComparator.PATH_COMPARATOR;
		/**
		 * 文件路径名逆序，区分大小写
		 */
		public static final Comparator<File> PathDesc = PathFileComparator.PATH_REVERSE;
		/**
		 * 文件路径名正序，不区分大小写
		 */
		public static final Comparator<File> PathAsc2 = PathFileComparator.PATH_INSENSITIVE_COMPARATOR;
		/**
		 * 文件路径名逆序，不区分大小写
		 */
		public static final Comparator<File> PathDesc2 = PathFileComparator.PATH_INSENSITIVE_REVERSE;
		/**
		 * 文件扩展名正序，区分大小写
		 */
		public static final Comparator<File> ExtensionAsc = ExtensionFileComparator.EXTENSION_COMPARATOR;
		/**
		 * 文件扩展名逆序，区分大小写
		 */
		public static final Comparator<File> ExtensionDesc = ExtensionFileComparator.EXTENSION_REVERSE;
		/**
		 * 文件扩展名正序，不区分大小写
		 */
		public static final Comparator<File> ExtensionAsc2 = ExtensionFileComparator.EXTENSION_INSENSITIVE_COMPARATOR;
		/**
		 * 文件扩展名逆序，不区分大小写
		 */
		public static final Comparator<File> ExtensionDesc2 = ExtensionFileComparator.EXTENSION_INSENSITIVE_REVERSE;
		/**
		 * 文件尺寸正序，目录尺寸视为0
		 */
		public static final Comparator<File> SizeAsc = SizeFileComparator.SIZE_COMPARATOR; 
		/**
		 * 文件尺寸逆序，目录尺寸视为0
		 */
		public static final Comparator<File> SizeDesc = SizeFileComparator.SIZE_REVERSE; 
		/**
		 * 文件尺寸正序，目录尺寸正常统计
		 */
		public static final Comparator<File> SizeAsc2 = SizeFileComparator.SIZE_SUMDIR_COMPARATOR; 
		/**
		 * 文件尺寸逆序，目录尺寸正常统计
		 */
		public static final Comparator<File> SizeDesc2 = SizeFileComparator.SIZE_SUMDIR_REVERSE;
		/**
		 * 最后修改时间正序 
		 */
		public static final Comparator<File> LastAsc = LastModifiedFileComparator.LASTMODIFIED_COMPARATOR;
		/**
		 * 最后修改时间逆序(最新修改的排序在前) 
		 */
		public static final Comparator<File> LastDesc = LastModifiedFileComparator.LASTMODIFIED_REVERSE;	
		/**
		 * 目录排序在文件之前 
		 */
		public static final Comparator<File> DirAsc = DirectoryFileComparator.DIRECTORY_COMPARATOR;
		/**
		 * 文件排序在目录之前 
		 */
		public static final Comparator<File> DirDesc = DirectoryFileComparator.DIRECTORY_REVERSE;	
		/**
		 * 默认比较器正序
		 */
		public static final Comparator<File> DefaultAsc = DefaultFileComparator.DEFAULT_COMPARATOR;
		/**
		 * 默认比较器逆序
		 */
		public static final Comparator<File> DefaultDesc = DefaultFileComparator.DEFAULT_REVERSE;
	 
		/**
		 * 联合比较器：根据多个比较器的规则综合比较
		 * 
		 * @param fileComparers
		 * @return
		 */
		@SafeVarargs
		public static Comparator<File> composite(Comparator<File> ...fileComparers){
			return new CompositeFileComparator(fileComparers);
		}
	}
}
